//
const ssr = require('../line-of-sight/namespace/SSRLoSNamespace');

cc.Class({
    extends: cc.Component,

    properties: {
    	robot: {
    		default: null,
    		type: cc.Node
    	},
        obstaclesGroup: {
            default         : null,
            type            : cc.Node
        },
        lightsGroup: {
            default         : null,
            type            : cc.Node
        },
    },

    start: function () {
        this._obstacleCount = 10;
        this._lightsCount = 0;
        this.losRenderLayer = this.node.getComponent("LoSRenderLayer");
        this.performance = this.node.getComponent("Performance");
        //
        this.robotObject = this.robot.getComponent("Robot");
        this.robotLoSComponent = this.robot.getComponent("SSRLoSComponentCore");
        this.robotLoSCore = this.robotLoSComponent.getLoSCore();
        this._initFloatingMenu();
        this._initDebugDraw();
    },
    _initFloatingMenu:function() {
        this._floatingMenu = cc.find("FloatingMenu").getChildByName("scrollView").getComponent("cc.ScrollView");
        this._losMaskRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_rayRenderMenuPanelItem");
        this._sightAreaRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_sightAreaRenderMenuPanelItem");
        this._sightLightRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_sightLightRenderMenuPanelItem");
        this._sightRangeRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_sightRangeRenderMenuPanelItem");
        this._rayRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_rayRenderMenuPanelItem");
        this._hitPointRenderMenuPanelItem  = this._floatingMenu.content.getChildByName("_hitPointRenderMenuPanelItem");
        this._sightVertRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_sightVertRenderMenuPanelItem");
        this._potentialBlockingEdgesRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_potentialBlockingEdgesRenderMenuPanelItem");
        this._blockingEdgesRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_blockingEdgesRenderMenuPanelItem");
        this._visibleEdgeRenderMenuPanelItem = this._floatingMenu.content.getChildByName("_visibleEdgeRenderMenuPanelItem");
        //
        this._sightRangePlusMenuPanelItem = this._floatingMenu.content.getChildByName("_sightRangePlusMenuPanelItem");
        this._sightRangeMinusMenuPanelItem = this._floatingMenu.content.getChildByName("_sightRangeMinusMenuPanelItem");
        this._sightAnglePlusMenuPanelItem = this._floatingMenu.content.getChildByName("_sightAnglePlusMenuPanelItem");
        this._sightAngleMinusMenuPanelItem = this._floatingMenu.content.getChildByName("_sightAngleMinusMenuPanelItem");
        this._sightSizeMenuPanelItem = this._floatingMenu.content.getChildByName("_sightSizeMenuPanelItem");
        this._sightRectMenuPanelItem = this._floatingMenu.content.getChildByName("_sightRectMenuPanelItem");
        this._dirtyDetectionPanelItem = this._floatingMenu.content.getChildByName("_dirtyDetectionPanelItem");
        //
        this._randomObstaclesPanelItem = this._floatingMenu.content.getChildByName("_randomObstaclesPanelItem");
        this._randomLightsPanelItem = this._floatingMenu.content.getChildByName("_randomLightsPanelItem");
        this._autoRotationPanelItem = this._floatingMenu.content.getChildByName("_autoRotationPanelItem");
    },
    _initDebugDraw:function() {
        this._sightRayDebugLabel = this._rayRenderMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._sightRayDebugLabel.string = "(-)";
        this._sightRayDebugLabel.node.color = this.losRenderLayer._losComponentRenderRay.getRender().strokeColor;

        this._hitPointDebugLabel = this._hitPointRenderMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._hitPointDebugLabel.string = "(-)";
        this._hitPointDebugLabel.node.color = this.losRenderLayer._losComponentRenderHitPoint.getRender().strokeColor;        

        this._potentialBlockingEdgeDebugLabel = this._potentialBlockingEdgesRenderMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._potentialBlockingEdgeDebugLabel.string = "(-)";
        this._potentialBlockingEdgeDebugLabel.node.color = this.losRenderLayer._losComponentRenderPotentialBlockingEdge.getRender().strokeColor;

        this._blockingEdgeDebugLabel = this._blockingEdgesRenderMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._blockingEdgeDebugLabel.string = "(-)";
        this._blockingEdgeDebugLabel.node.color = this.losRenderLayer._losComponentRenderBlockingEdge.getRender().strokeColor;

        this._visibleEdgeDebugLabel = this._visibleEdgeRenderMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._visibleEdgeDebugLabel.string = "(-)";
        this._visibleEdgeDebugLabel.node.color = this.losRenderLayer._losComponentRenderVisibleEdge.getRender().strokeColor;

        this._sightVertDebugLabel = this._sightVertRenderMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._sightVertDebugLabel.string = "(-)";
        this._sightVertDebugLabel.node.color = this.losRenderLayer._losComponentRenderSightVert.getRender().strokeColor;
        
        this._sightRangeDebugLabel = this._sightRangePlusMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._sightRangeDebugLabel.string = "(-)";

        this._sightAngleDebugLabel = this._sightAnglePlusMenuPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._sightAngleDebugLabel.string = "(-)";

        this._randomObstaclesDebugLabel = this._randomObstaclesPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._randomObstaclesDebugLabel.string = "(✖️ 10)";

        this._randomLightsDebugLabel = this._randomLightsPanelItem.getChildByName("debug").getComponent("cc.Label");
        this._randomLightsDebugLabel.string = "(✖️ 0)";
    },
    //
    losMaskRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableLoSMask();
        }
        else {
            this.enableLoSMask();
        }  
    },
    sightAreaRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableSightArea();
        }
        else {
            this.enableSightArea();
        }  
    },
    sightLightRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableSightLight();
        }
        else {
            this.enableSightLight();
        }  
    },
    sightRangeRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableSightRangeRender();
        }
        else {
            this.enableSightRangeRender();
        }  
    },
    rayRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableRayRender();
        }
        else {
            this.enableRayRender();
        }
    },
    hitPointRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableHitPointRender()
        }
        else {
            this.enableHitPointRender();
        }
    },
    sightVertRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableSightVertRender()
        }
        else {
            this.enableSightVertRender();
        }
    },
    potentialBlockingEdgesRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disablePotentialBlockingEdgesRender();
        }
        else {
            this.enablePotentialBlockingEdgesRender(); 
        }
    },
    blockingEdgesRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableBlockingEdgesRender();
        }
        else {
            this.enableBlockingEdgesRender()   
        }
    },
    visibleEdgeRenderMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableVisibleEdgesRender();
        }
        else {
            this.enableVisibleEdgesRender();
        }
    },
    sightRangeMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableSightRange();
        }
        else {
            this.enableSightRange();
        }  
    },
    sightRangePlusMenuCallback:function(sender, data) {
        this.sightRangePlus();
    },
    sightRangeMinusMenuCallback:function(sender, data) {
        this.sightRangeMinus();
    },
    endAnglePlusMenuCallback:function(sender, data) {
        this.sightRangeMinus();
    },
    sightAnglePlusMenuCallback:function(sender, data) {
        this.sightAnglePlus();
    },
    sightAngleMinusMenuCallback:function(sender, data) {
        this.sightAngleMinus();
    },
    endAnglePlusMenuCallback:function(sender, data) {
        this.sightEndAnglePlus();
    },
    endAngleMinusMenuCallback:function(sender, data) {
        this.sightEndAngleMinus();
    },
    dirtyDetectionMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableDirtyDetection();
        }
        else {
            this.enableDirtyDetection();
        }  
    },
    sightRectMenuCallback:function(sender) {
        this._sightSizeMenuPanelItem.getComponent(cc.Toggle).isChecked = false;
        if (sender.isChecked == 0) {
            this.robotLoSCore.enableAutoGenerateBoundary();
        }
        else {
            // fixed custom sight rect quarter of the screen
            this.robotLoSCore.setSightRect(cc.rect(-300, -300, 600, 600));
        }
    },
    sightSizeMenuCallback:function(sender) {
        this._sightRectMenuPanelItem.getComponent(cc.Toggle).isChecked = false;
        if (sender.isChecked == 0) {
            this.robotLoSCore.enableAutoGenerateBoundary();
        }
        else {
            // custom sight size half of the screen
            this.robotLoSCore.setSightSize(cc.winSize.width / 2, cc.winSize.height / 2);
        }
    },
    followMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableFollow();
        }
        else {
            this.enableFollow();
        }  
    },
    randomObstaclesMenuCallback:function(sender, data) {
        this._obstacleCount += 10;
        this._randomObstaclesDebugLabel.string = "(✖️ " + this._obstacleCount + ")";
        this.performance.randomObstacles(this._obstacleCount);
    },
    randomLightsMenuCallback:function(sender, data) {
        this._lightsCount += 2;
        this._randomLightsDebugLabel.string = "(✖️ " + this._lightsCount + ")";
        this.performance.randomLights(this._lightsCount);
    },
    autoRotationMenuCallback:function(sender, data) {
        if (sender.isChecked == 0) {
            this.disableAutoRotation();
        }
        else {
            this.enableAutoRotation();
        }  
    },
    /*********************************** menu logic ***********************************/
    disableLoSMask:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losMaskNode.node.active = false;
    },
    enableLoSMask:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losMaskNode.node.active = true;
    },
    enableSightArea:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightArea.node.active = true;
    },
    disableSightArea:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightArea.node.active = false;
        this.losRenderLayer._losComponentRenderSightArea.clear();
    },
    enableSightLight:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightLight.node.active = true;
    },
    disableSightLight:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightLight.node.active = false;
        this.losRenderLayer._losComponentRenderSightLight.clear();
    },
    enableSightRangeRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightRange.node.active = true;
    },
    disableSightRangeRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightRange.node.active = false;
        this.losRenderLayer._losComponentRenderSightRange.clear();
    },
    enableRayRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderRay.node.active = true;
    },
    disableRayRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderRay.node.active = false;
        this.losRenderLayer._losComponentRenderRay.clear();
    },
    enableHitPointRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderHitPoint.node.active = true;
    },
    disableHitPointRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderHitPoint.node.active = false;
        this.losRenderLayer._losComponentRenderHitPoint.clear();
    },
    enableSightVertRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightVert.node.active = true;
    },
    disableSightVertRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderSightVert.node.active = false;
        this.losRenderLayer._losComponentRenderSightVert.clear();
    },
    enablePotentialBlockingEdgesRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderPotentialBlockingEdge.node.active = true;
    },
    disablePotentialBlockingEdgesRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderPotentialBlockingEdge.node.active = false;
        this.losRenderLayer._losComponentRenderPotentialBlockingEdge.clear();
    },
    enableBlockingEdgesRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderBlockingEdge.node.active = true;
    },
    disableBlockingEdgesRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderBlockingEdge.node.active = false;
        this.losRenderLayer._losComponentRenderBlockingEdge.clear();
    },
    enableVisibleEdgesRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderVisibleEdge.node.active = true;
    },
    disableVisibleEdgesRender:function() {
        this.robotObject.isForceLoSUpdate = true;
        this.losRenderLayer._losComponentRenderVisibleEdge.node.active = false;
        this.losRenderLayer._losComponentRenderVisibleEdge.clear();
    },
    enableDirtyDetection:function() {
        if (this.robot) {
            var obstacles = this.robotLoSCore.getObstacles();
            for (var i = 0; i < obstacles.length; i ++) {
                obstacles[i].enableDirtyDetection();
            }
        }
        var lights = this.lightsGroup.getChildren();
        for (var i = 0; i < lights.length; i ++) {
            var obstacles = lights[i].getComponent("SSRLoSComponentCore").getLoSCore().getObstacles();
            for (var j = 0; j < obstacles.length; j ++) {
                obstacles[j].enableDirtyDetection();
            }
        }
        this._isTransformationDirtyDetectionOn = true;
    },
    disableDirtyDetection:function() {
        if (this.robot) {
            var obstacles = this.robotLoSCore.getObstacles();
            for (var i = 0; i < obstacles.length; i ++) {
                obstacles[i].disableDirtyDetection();
            }
        }
        var lights = this.lightsGroup.getChildren();
        for (var i = 0; i < lights.length; i ++) {
            var obstacles = lights[i].getComponent("SSRLoSComponentCore").getLoSCore().getObstacles();
            for (var j = 0; j < obstacles.length; j ++) {
                obstacles[j].disableDirtyDetection();
            }
        }
        this._isTransformationDirtyDetectionOn = false;
    },
    enableSightRange:function() {
        if (this.robotLoSCore.getRadius() == -1) {
            this.robotLoSCore.setRadius(32 * 4);
        }
        this.robotObject.isForceLoSUpdate = true;
        this._sightRangePlusMenuPanelItem.getComponent(cc.Button).interactable = true;
        this._sightRangeMinusMenuPanelItem.getComponent(cc.Button).interactable = true;
        this._sightAnglePlusMenuPanelItem.getComponent(cc.Button).interactable = true;
        this._sightAngleMinusMenuPanelItem.getComponent(cc.Button).interactable = true;
        this._sightSizeMenuPanelItem.getComponent(cc.Button).interactable = false;
        this._sightRectMenuPanelItem.getComponent(cc.Button).interactable = false;

        this._sightRangeDebugLabel.string = " (" + this.robotLoSCore.getRadius() + ")";
        this._sightAngleDebugLabel.string = " (" + this.robotLoSCore.getCentralAngle() + ")";
    },
    disableSightRange:function() {
        this.robotLoSCore.setCentralAngle(ssr.LoS.Constant.FULL_ANGLE);
        this.robotLoSCore.setRadius(ssr.LoS.Constant.UNLIMITED_RANGE);
        this.robotObject.isForceLoSUpdate = true;
        this._sightRangePlusMenuPanelItem.getComponent(cc.Button).interactable = false;
        this._sightRangeMinusMenuPanelItem.getComponent(cc.Button).interactable = false;
        this._sightAnglePlusMenuPanelItem.getComponent(cc.Button).interactable = false;
        this._sightAngleMinusMenuPanelItem.getComponent(cc.Button).interactable = false;
        this._sightSizeMenuPanelItem.getComponent(cc.Button).interactable = true;
        this._sightRectMenuPanelItem.getComponent(cc.Button).interactable = true;

        this._sightRangeDebugLabel.string = "N/A";
        this._sightAngleDebugLabel.string = "N/A";
    },
    sightRangeMinus:function() {
        if (this.robot) {
            var radius = this.robotLoSCore.getRadius();
            if (radius <= 0) {
                return;
            }
            this.robotLoSCore.setRadius(radius - 8);
        }
        this.robotObject.isForceLoSUpdate = true;
        this._sightRangeDebugLabel.string = " (" + this.robotLoSCore.getRadius() + ")";
    },
    sightRangePlus:function() {
        if (this.robot) {
            var radius = this.robotLoSCore.getRadius();
            this.robotLoSCore.setRadius(radius + 8);
        }
        this.robotObject.isForceLoSUpdate = true;
        this._sightRangeDebugLabel.string = " (" + this.robotLoSCore.getRadius() + ")";
    },
    sightAnglePlus:function() {
        if (this.robot) {
            var angle = this.robotLoSCore.getCentralAngle();
            this.robotLoSCore.setCentralAngle(angle + 2);
        }
        this.robotObject.isForceLoSUpdate = true;
        this._sightAngleDebugLabel.string = " (" + this.robotLoSCore.getCentralAngle() + "°)";
    },
    sightAngleMinus:function() {
        if (this.robot) {
            var angle = this.robotLoSCore.getCentralAngle();
            this.robotLoSCore.setCentralAngle(angle - 2);
        }
        this.robotObject.isForceLoSUpdate = true;
        this._sightAngleDebugLabel.string = " (" + this.robotLoSCore.getCentralAngle() + "°)";
    },
    sightEndAnglePlus:function() {
        if (this.robot) {
            var endAngle = this.robotLoSCore.getEndAngle();
            this.robotLoSCore.setEndAngle(endAngle + 2);
        }
        this.robotObject.isForceLoSUpdate = true;
        this._sightAngleDebugLabel.string = " (" + this.robotLoSCore.getCentralAngle() + "°)";
    },
    sightEndAngleMinus:function() {
        if (this.robot) {
            var endAngle = this.robotLoSCore.getEndAngle();
            this.robotLoSCore.setEndAngle(endAngle - 2);
        }
        this.robotObject.isForceLoSUpdate = true;
        this._sightAngleDebugLabel.string = " (" + this.robotLoSCore.getCentralAngle() + "°)";
    },
    disableFollow:function() {
        this.robotObject.useCamera = false;
    },
    enableFollow:function() {
        this.robotObject.useCamera = true;
        this.robotObject.isForceLoSUpdate = true;
    },
    disableAutoRotation:function() {
        var obstaclesArray = this.obstaclesGroup.getChildren();
        for (var i = 0; i < obstaclesArray.length; i ++) {
            obstaclesArray[i].stopAllActions();
        }
    },
    enableAutoRotation:function() {
        var obstaclesArray = this.obstaclesGroup.getChildren();
        for (var i = 0; i < obstaclesArray.length; i ++) {
            obstaclesArray[i].runAction(
                cc.repeatForever(
                    cc.rotateBy(10, 360)
                )
            );
        }
    },
    //
    updateDebugDraw:function() {
        var rayCount = this.robotLoSCore.getRayCount();
        this._sightRayDebugLabel.string = (" (" + rayCount + ")");

        var hitPointCount = this.robotLoSCore.getHitPointCount();
        this._hitPointDebugLabel.string = (" (" + hitPointCount + ")");

        var sightVertCount = this.robotLoSCore.getSightAreaVertCount();
        this._sightVertDebugLabel.string = (" (" + sightVertCount + ")");

        var potentialBlockingEdgeCount = this.robotLoSCore.getPotentialBlockingEdgeCount();
        this._potentialBlockingEdgeDebugLabel.string = (" (" + potentialBlockingEdgeCount + ")");

        var blockingEdgeCount = this.robotLoSCore.getBlockingEdgeCount();
        this._blockingEdgeDebugLabel.string = (" (" + blockingEdgeCount + ")");

        var visibleEdgeCount = this.robotLoSCore.getVisibleEdgeCount();
        this._visibleEdgeDebugLabel.string = (" (" + visibleEdgeCount + ")");
    }
});
